#include "stdafx.h"
#include "gp_Ax2.h"
#include "gp_Ax1.h"
#include "gp_Pnt.h"
#include "gp_Trsf.h"
#include "gp_Vec.h"
#include "gp_Circ.h"
#include "gp_Pnt.h"
#include "gp.h"
#include <cmath>
#include <assert.h>

void gp_Circ::Mirror (const gp_Pnt& P)
{ pos.Mirror(P); }

gp_Circ gp_Circ::Mirrored (const gp_Pnt& P) const
{
  gp_Circ C = *this;
  C.pos.Mirror (P);
  return C; 
}

void gp_Circ::Mirror (const gp_Ax1& A1)
{ pos.Mirror(A1); }

gp_Circ gp_Circ::Mirrored (const gp_Ax1& A1) const
{
  gp_Circ C = *this;
  C.pos.Mirror (A1);
  return C; 
}

void gp_Circ::Mirror (const gp_Ax2& A2)
{ pos.Mirror(A2); }

gp_Circ gp_Circ::Mirrored (const gp_Ax2& A2) const
{
  gp_Circ C = *this;
  C.pos.Mirror (A2);
  return C; 
}

 gp_Circ::gp_Circ () : radius(DBL_MAX)
{  }

 gp_Circ::gp_Circ (const gp_Ax2& A2,
			 const double R) : pos(A2), radius(R)
{
	 Standard_ConstructionError_Raise_if(R < 0.0, "");
}

 void gp_Circ::SetAxis (const gp_Ax1& A1)
{ pos.SetAxis (A1); }

 void gp_Circ::SetLocation (const gp_Pnt& P)
{ pos.SetLocation (P); }

 void gp_Circ::SetPosition (const gp_Ax2& A2)
{ pos = A2; }

 void gp_Circ::SetRadius (const double R)
{ 
	 Standard_ConstructionError_Raise_if(R < 0.0, "");
  radius = R;
}

   double gp_Circ::Area() const
{ return M_PI * radius * radius; }

 const gp_Ax1& gp_Circ::Axis () const
{ return pos.Axis(); }

   double gp_Circ::Length() const
{ return 2. * M_PI * radius; }

 const gp_Pnt& gp_Circ::Location () const
{ return pos.Location(); }

   const gp_Ax2& gp_Circ::Position() const
{ return pos; }

   double gp_Circ::Radius() const
{ return radius; }

 gp_Ax1 gp_Circ::XAxis () const
{return gp_Ax1(pos.Location(), pos.XDirection());}

 gp_Ax1 gp_Circ::YAxis () const
{return gp_Ax1(pos.Location(), pos.YDirection());}

 double gp_Circ::Distance (const gp_Pnt& P) const
{ return sqrt(SquareDistance(P)); }

 double gp_Circ::SquareDistance (const gp_Pnt& P) const
{
  gp_Vec V(Location(),P);
  double x = V.Dot(pos.XDirection());
  double y = V.Dot(pos.YDirection());
  double z = V.Dot(pos.Direction ());
  double t = sqrt( x*x + y*y) - radius;
  return (t*t + z*z);
}

 bool gp_Circ::Contains
(const gp_Pnt& P,
 const double LinearTolerance) const
{ return Distance(P) <= LinearTolerance; }

 void gp_Circ::Rotate (const gp_Ax1& A1,
			     const double Ang)
{ pos.Rotate(A1, Ang); }

 gp_Circ gp_Circ::Rotated (const gp_Ax1& A1,
				 const double Ang) const
{
  gp_Circ C = *this;
  C.pos.Rotate(A1, Ang);
  return C; 
}

 void gp_Circ::Scale (const gp_Pnt& P,
			    const double S)
{
  radius *= S;
  if (radius < 0) radius = - radius;
  pos.Scale(P, S);
}

 gp_Circ gp_Circ::Scaled (const gp_Pnt& P,
				const double S) const 
{
  gp_Circ C = *this;
  C.radius *= S;
  if (C.radius < 0) C.radius = - C.radius;
  C.pos.Scale(P, S);
  return C; 
}

 void gp_Circ::Transform (const gp_Trsf& T)
{
  radius *= T.ScaleFactor();
  if (radius < 0) radius = - radius;
  pos.Transform(T);
}

 gp_Circ gp_Circ::Transformed (const gp_Trsf& T) const
{
  gp_Circ C = *this;
  C.radius *= T.ScaleFactor();
  if (C.radius < 0) C.radius = - C.radius;
  C.pos.Transform(T);
  return C;
}

 void gp_Circ::Translate (const gp_Vec& V)
{ pos.Translate(V); }

 gp_Circ gp_Circ::Translated (const gp_Vec& V) const 
{
  gp_Circ C = *this;
  C.pos.Translate(V);
  return C; 
}

 void gp_Circ::Translate (const gp_Pnt& P1,
				const gp_Pnt& P2)
{pos.Translate(P1,P2);}

 gp_Circ gp_Circ::Translated (const gp_Pnt& P1,
				    const gp_Pnt& P2) const
{
  gp_Circ C = *this;
  C.pos.Translate(P1, P2);
  return C; 
}
